package com.jp.bigimageload;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapRegionDecoder;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Scroller;

import androidx.annotation.Nullable;

import java.io.IOException;
import java.io.InputStream;

public class MNBigView extends View implements GestureDetector.OnGestureListener, View.OnTouchListener {
    private final Rect mRect;
    private final BitmapFactory.Options mOptions;
    private final GestureDetector mGestureDetector;
    private final Scroller mScroller;
    private int mImageWidth;
    private int mImageHeight;
    private BitmapRegionDecoder mDecoder;
    private int mViewWidth;
    private int mViewHeight;
    private float mScale;
    private Bitmap mBitmap;
    private Matrix matrix = new Matrix();

    public MNBigView(Context context) {
        this(context,null);
    }

    public MNBigView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs,0);
        // 你的技术短板在哪里？  认识自己；
        // 你觉得你值钱的地方在哪里？  java + android 后台 html css js 数据库  缓存数据（db） 社交项目
        // 你们值钱？独立开发？懂app优化？懂管理？我学历高？
        // 个人介绍：本人拥有2年java以及2年android开发经验，擅于团队合作/为人诚恳，拥有一定的项目管理经验，以及独立开发app的能力；

        // 为什么想做架构师？

        // android高级开发工程师

        // UI（动画，特效，自定义View/ViewGroup，baidu）  UI原理，UI事件传递机制；动画你写过没？贝塞尔曲线？
        // 架构（压根不用学习，各种第三方随便用）okhttp原理什么？能不能说一下Glide里面生命周期怎么处理的？Okhttp线程池怎么写的？
        // 热修复用过没？知道原理吗？遇到过什么问题没，怎么解决的？
        // 性能优化（你做的app安全吗？能扛多少用户？如果有app崩溃了，你怎么处理的？你有方案没有？）
        // 音视频开发（会吗？）
        // 内存泄漏 数据结构 线程  （java核心基础知识）

        // 懂binder，熟悉okhttp，熟悉a 熟悉b 熟悉设计模式 mvvm mvp

        //懂底层的Framework和ROM定制的话，去之智能硬件的公司也非常吃香
        // 工作岗位问题：做rom开发的人 毕竟少很多；相对于app开发来说；手机厂商（华为 oppo 小米 vivo）  定制rom = app开发
        // rom 针对android系统；无法跟具体的业务对接；请问你还有上升空间吗？定制一个rom 1-10个功能；加一个白名单；
        // 一个系统永远都是运行在一个机器上；
        // 做app 登录注册 登陆注册
    }

    public MNBigView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
          super(context, attrs, defStyleAttr);
        mRect = new Rect();
        mOptions = new BitmapFactory.Options();
        mGestureDetector = new GestureDetector(context,this);
        mScroller = new Scroller(context);
        setOnTouchListener(this);
    }

    // 传入图片
    public void setImage(InputStream is){
        // 获取图片的宽和高
        mOptions.inJustDecodeBounds = true;
        BitmapFactory.decodeStream(is,null,mOptions);
        mImageWidth = mOptions.outWidth;
        mImageHeight = mOptions.outHeight;

        // 开启复用
        mOptions.inMutable = true;
        mOptions.inPreferredConfig = Bitmap.Config.RGB_565;
        // 图片由像素点组成 像素点由三原色的信息组成

        mOptions.inJustDecodeBounds = false;

        // 创建区域解码器
        try {
            mDecoder = BitmapRegionDecoder.newInstance(is,false);
        } catch (IOException e) {
            e.printStackTrace();
        }

        requestLayout();

    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        mViewWidth = getMeasuredWidth();
        mViewHeight = getMeasuredHeight();

        // 确定图片的加载区域
        mRect.left = 0;
        mRect.top = 0;
        mRect.right = mImageWidth;
        mScale = mViewWidth/(float)mImageWidth;
        mRect.bottom = (int)(mViewHeight/mScale);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if(mDecoder == null){
            return;
        }
        mOptions.inBitmap = mBitmap;
        mBitmap = mDecoder.decodeRegion(mRect,mOptions);
        matrix.setScale(mScale,mScale);
        canvas.drawBitmap(mBitmap,matrix,null);
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        return mGestureDetector.onTouchEvent(event);
    }

    @Override
    public boolean onDown(MotionEvent e) {
        if(!mScroller.isFinished()){
            mScroller.forceFinished(true);
        }
        return true;
    }

    @Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
        mRect.offset(0,(int)distanceY);
        if(mRect.bottom > mImageHeight){
            mRect.bottom = mImageHeight;
            mRect.top = mImageHeight-(int)(mViewHeight/mScale);
        }
        if(mRect.top < 0){
            mRect.top = 0;
            mRect.bottom = (int)(mViewHeight/mScale);
        }
        invalidate();
        return false;
    }

    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
        mScroller.fling(0,mRect.top,0,(int)-velocityY,0,0,0,
                mImageHeight-(int)(mViewHeight/mScale));
        return false;
    }

    @Override
    public void computeScroll() {
        if(mScroller.isFinished()){
            return;
        }
        if(mScroller.computeScrollOffset()){
            mRect.top = mScroller.getCurrY();
            mRect.bottom = mRect.top+(int)(mViewHeight/mScale);
            invalidate();
        }
    }

    @Override
    public void onShowPress(MotionEvent e) {

    }

    @Override
    public boolean onSingleTapUp(MotionEvent e) {
        return false;
    }



    @Override
    public void onLongPress(MotionEvent e) {

    }
}
